#pragma once
#include "VulkanView.h"
#include "Runtime/CGI/CGITexture.h"
#include "VulkanResource.h"

namespace Alice
{
    struct CGIVulkanRHIExternalImageDeleteCallbackInfo;
    class CGIVulkanTexture : public CGITexture{
    public:
        VkImage mImage;
	    VkImageUsageFlags mImageUsageFlags;
        VkFormat mStorageFormat;  // Removes SRGB if requested, used to upload data
        VkFormat mViewFormat;  // Format for SRVs, render targets
        VkImageAspectFlags mFullAspectMask;
        VkImageAspectFlags mPartialAspectMask;
	    VkImageTiling mTiling;
	    VkImageLayout mDefaultLayout;
    	CGIVulkanView* mDefaultView;
        CGIVulkanTexture();
        CGIVulkanTexture(VulkanDevice& InDevice, const CGITextureCreateDesc& InCreateDesc, VkImage InImage, const CGIVulkanRHIExternalImageDeleteCallbackInfo& InExternalImageDeleteCallbackInfo);
        // Full includes Depth+Stencil
        inline VkImageAspectFlags GetFullAspectMask() const
        {
            return mFullAspectMask;
        }

        // Only Depth or Stencil
        inline VkImageAspectFlags GetPartialAspectMask() const
        {
            return mPartialAspectMask;
        }
        inline bool IsDepthOrStencilAspect() const
        {
            return (mFullAspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0;
        }
        inline bool SupportsSampling() const
        {
            return EnumHasAllFlags(GPixelFormats[(uint32)GetDesc().Format].Capabilities, EPixelFormatCapabilities::TextureSample) &&
                ((mImageUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) != 0);
        }
        inline VkImageViewType GetViewType() const
        {
            return UETextureDimensionToVkImageViewType(GetDesc().Dimension);
        }
        inline uint32 GetNumberOfArrayLevels() const
        {
            switch (GetViewType())
            {
            case VK_IMAGE_VIEW_TYPE_1D:
            case VK_IMAGE_VIEW_TYPE_2D:
            case VK_IMAGE_VIEW_TYPE_3D:
                return 1;
            case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
                return GetDesc().ArraySize;
            case VK_IMAGE_VIEW_TYPE_CUBE:
                return 6;
            case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
                return 6 * GetDesc().ArraySize;
            default:
                return 1;
            }
        }
        void SetInitialImageState(VulkanCommandListContext& Context, VkImageLayout InitialLayout, bool bClear, const FClearValueBinding& ClearValueBinding, bool bIsTransientResource);
    };
}
